PROGRAMME D'AUTOMATISATION
Bon connaitre le fonctionnement de l'IAT c'est très bien, mais le reverser
c'est une autre histoire, le véritable problème c'est pas l'IAT
lui-même mais plutôt la reconstruction des différents liens.
Comme je l'ai déjà dit, j'avais réalisé un petit
programme qui reconstruisait l'IAT et rétablissait les liens les plus
communs. Mais faut pas se voiler la face, il est franchement inefficace parce
qu'il y a toujours à un moment ou à un autre un type de lien fantaisiste
qui fini par faire échouer l'ensemble. Donc l'IAT, ne faîtes pas
l'impasse dessus ce serait bien dommage, mais je pense qu'on peut s'en passer
en étant un peu plus malin.
Il y a deux grands principes pour appeler une fonction. Soit on l'extrait à
partir de l'IAT comme on l'a vue précédemment, soit on a la possibilité
de retouver une fonction quelconque en l'appelant à partir des fonctions
LoadLibraryA/GetProcAddress.
Le bon point c'est que si vous décidez de reverser un programme, il n'y
a aucun problème si LoadLibraryA et GetProcAddress sont présents
dans son IAT.
Le mauvais point forcément, c'est que c'est impossible si ces deux fonctions
ne sont pas dans son IAT. Et là... Catastrophe... Le tut s'arrête
là donc...
Hep!! nan nan... pas si vite!!! Si vous allez sur le site de qui-vous-savez,
vous trouverez un programme écrit par y0da. La particularité de
ce programme c'est justement de retrouver l'handle de Kernel32 puis les adresses
de LoadLibrary et GetProcAddress sans utiliser AUCUNE api. Ouuuu !!! Je sens
déjà qu'avant même d'avoir pu lire la suite, votre cerveau
commence à bouillonner ... les idées se forment, indistinctes
encore, mais une voie se dessine... Ne serait-il pas possible de créer
un pseudo-IAT, une nouvelle section recherchant par ses propres moyens les adresses
d'éventuelles nouvelles fonctions, et ça uniquement à partir
de mnémoniques et rien d'autre ? Bien sûr que c'est possible. Et
non seulement c'est faisable, mais c'est FAIT.
Le principe c'est sur un programme cible lui ajouter une nouvelle section, rediriger
l'EntryPoint sur elle puis une fois son travail effectué, retourner l'EntryPoint
vers son adresse d'origine. Le contenu de cette nouvelle section, c'est ni plus
ni moins que le programme de y0da lui-même, ammélioré quelque
peu.
Cette section est un véritable programme à part entière.
Elle contient à la fois des data et du code.
Mon programme injecte dans la cible le code de y0da et dans sa zone data les
noms des fonctions (avec leurs DLL parentes) que vous souhaitez ajouter, et
rien d'autre.
Maintenant si vous lancer votre cible, le code de y0da incorporé, va
retrouver les noms des fonctions et à partir d'elles il va retrouver
leurs adresses dynamiquement. On arrive donc à nos fins, les adresses
des nouvelles fonctions deviennent disponibles. Ces adresses sont elles-mêmes
ré-inscritent dans la zone data de ma section uniquement si la cible
est en route (si vous jetez un coup d'oeil en DeadListing vous ne verrez jamais
aucune adresse, elles sont créées et recréées à
la volée).
J'ai dit dynamiquement, parce que les adresses retrouvées ne sont pas
statiques, et c'est là la grande force de ce principe. Si vous avez une
certaine version d'une DLL, l'adresse d'une fonction précise sera valide,
et pour cette même DLL mais sous une version plus évolue, l'adresse
de la fonction même ayant changée, mon loader retrouvera sa nouvelle
adresse. C'est exactement ce qui est fait au niveau d'un vrai IAT. L'énorme
avantage, c'est qu'on ne touche absolument pas au véritable IAT et donc
aucun lien n'a besoin d'être retouché. Simplement les nouvelles
adresses sont mises à part dans la nouvelle section, c'est tout...
Bon, je n'irai pas plus loin. L'utilisation de mon programme est vraiment trivial.
Et puisque vous lisez ces lignes, c'est que vous projetez d'ajouter des fonctions
à un programme cible, ce qui signifie que vous possédez un niveau
suffisament avancé en reverse, donc je ne vous bassinerai pas plus longtemps
en vous impossant un exemple. Maintenant, c'est à vous de jouer!
Ah juste deux points avant de nous quitter, GetProcAddress retrouve les adresses
des fonctions grâce à leurs noms, donc pour les fonctions exportées
BY ORDINAL ne vous étonnez pas si elles refusent de se plier à
vos besoins. Mais bon, vous en utilisez souvent vous ?
Egalement, les adresses des nouvelles fonctions ne sont disponibles qu'une fois
que ma section aie terminée son travail forcément donc si vous
projetez de créer une section de plus pour placer votre propre code,
vous devez effecter la redirection vers la vôtre seulement à la
fin de la mienne. Mais sachez que ma section est normalement bien suffusante
pour y placer aussi le vôtre.
Par Morgatte